package org.celery.modules.other.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.celery.modules.goods.entity.Goods;
import org.celery.modules.goods.entity.GoodsStyle;
import org.celery.modules.goods.enums.GoodsStatusEnum;
import org.celery.modules.goods.service.IGoodsService;
import org.celery.modules.order.entity.Order;
import org.celery.modules.order.enums.OrderStatusEnum;
import org.celery.modules.order.enums.OrderStatusShipEnum;
import org.celery.modules.order.service.IOrderService;
import org.celery.modules.other.vo.StatisticDateGoodsVo;
import org.celery.modules.other.vo.StatisticSummaryVo;
import org.springblade.core.boot.ctrl.BladeController;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.utils.SecureUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.jackson.JsonUtil;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.system.entity.User;
import org.springblade.modules.system.service.IUserService;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 统计 控制器
 *
 * @author Celery
 * @since 2022-04-16
 */
@RestController
@AllArgsConstructor
@RequestMapping("celery-other/statistics")
@Api(value = "统计")
public class StatisticsController extends BladeController {

    private final IUserService userService;
    private final IOrderService orderService;
    private final IGoodsService goodsService;

    /**
     * 概要信息
     */
    @GetMapping("/total")
    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "概要信息")
    public R<StatisticSummaryVo> total(BladeUser bladeUser) {
        StatisticSummaryVo statisticSummary = new StatisticSummaryVo();
        List<Long> userIdList = new ArrayList<>();

        if (!SecureUtil.isAdministrator()) {
            userIdList = userService.getUnderUserIdList(bladeUser).stream().map(User::getId).collect(Collectors.toList());
        }

        QueryWrapper<Order> queryWrapperOrder = new QueryWrapper<>();
        queryWrapperOrder.lambda().eq(Order::getStatus, OrderStatusEnum.NORMAL.getStatus());
        if (!SecureUtil.isAdministrator()) {
            queryWrapperOrder.lambda().in(Order::getFromUser, userIdList);
        }

        List<Order> orderList = orderService.list(queryWrapperOrder);

        // 销售订单、金额、待审订单
        statisticSummary.setOrderSellCount(orderList.size());
        BigDecimal sellOrderAmount = new BigDecimal(0);
        int orderUnderReview = 0;

        for (Order order: orderList) {
            sellOrderAmount = sellOrderAmount.add(order.getTotalAmount());
            if (order.getShipStatus().equals(OrderStatusShipEnum.TO_BE_CONFIRM.getStatus())) {
                orderUnderReview++;
            }
        }
        statisticSummary.setOrderUnderReview(orderUnderReview);
        statisticSummary.setOrderSellAmount(sellOrderAmount);


        QueryWrapper<Goods> queryWrapperGoods = new QueryWrapper<>();
        if (!SecureUtil.isAdministrator()) {
            queryWrapperGoods.lambda().in(Goods::getCreateUser, userIdList);
        }

        List<Goods> goodsList = goodsService.list(queryWrapperGoods);

        // 商品发布数量、待审核数量、总数
        statisticSummary.setGoodsCount(goodsList.size());
        int goodsUnderReview = 0;
        for (Goods goods: goodsList) {
            if (goods.getStatus() == GoodsStatusEnum.STANDBY.getStatus()) {
                goodsUnderReview++;
            }
        }
        statisticSummary.setGoodsUnderReview(goodsUnderReview);

        return R.data(statisticSummary);
    }

    /**
     * 概要信息
     */
    @GetMapping("/summary")
    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "概要信息")
    public R<StatisticSummaryVo> summary(@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") Date startTime, @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") Date endTime, BladeUser bladeUser) {
        if (Func.isEmpty(startTime)) {
            String today = DateUtil.formatDate(DateUtil.now());
            startTime = DateUtil.parse(today + " 00:00:00", DateUtil.PATTERN_DATETIME);
            endTime = DateUtil.parse(today + " 23:59:59", DateUtil.PATTERN_DATETIME);
        }


        StatisticSummaryVo statisticSummary = new StatisticSummaryVo();
        List<Long> userIdList = new ArrayList<>();

        if (!SecureUtil.isAdministrator()) {
            userIdList = userService.getUnderUserIdList(bladeUser).stream().map(User::getId).collect(Collectors.toList());
        }

        QueryWrapper<Order> queryWrapperOrder = new QueryWrapper<>();
        queryWrapperOrder.lambda().between(Order::getCreateTime, startTime, endTime).eq(Order::getStatus, OrderStatusEnum.NORMAL.getStatus());
        if (!SecureUtil.isAdministrator()) {
            queryWrapperOrder.lambda().in(Order::getFromUser, userIdList);
        }

        List<Order> orderList = orderService.list(queryWrapperOrder);

        // 销售订单、金额、待审订单
        statisticSummary.setOrderSellCount(orderList.size());
        BigDecimal sellOrderAmount = new BigDecimal(0);
        int orderUnderReview = 0;

        for (Order order: orderList) {
            sellOrderAmount = sellOrderAmount.add(order.getTotalAmount());
            if (order.getShipStatus().equals(OrderStatusShipEnum.TO_BE_CONFIRM.getStatus())) {
                orderUnderReview++;
            }
        }
        statisticSummary.setOrderUnderReview(orderUnderReview);
        statisticSummary.setOrderSellAmount(sellOrderAmount);


        QueryWrapper<Goods> queryWrapperGoods = new QueryWrapper<>();
        queryWrapperGoods.lambda().between(Goods::getCreateTime, startTime, endTime);
        if (!SecureUtil.isAdministrator()) {
            queryWrapperGoods.lambda().in(Goods::getCreateUser, userIdList);
        }

        List<Goods> goodsList = goodsService.list(queryWrapperGoods);

        // 商品发布数量、待审核数量、总数
        statisticSummary.setGoodsCount(goodsList.size());
        int goodsUnderReview = 0;
        for (Goods goods: goodsList) {
            if (goods.getStatus() == GoodsStatusEnum.STANDBY.getStatus()) {
                goodsUnderReview++;
            }
        }
        statisticSummary.setGoodsUnderReview(goodsUnderReview);

        return R.data(statisticSummary);
    }

    /**
     * 商品历史排行
     */
    @GetMapping("/history-ranking-goods")
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "商品历史排行")
    public R<List<Goods>> historyRankingGoods(BladeUser bladeUser) {
        QueryWrapper<Goods> queryWrapper = new QueryWrapper<>();
        if (!SecureUtil.isAdministrator()) {
            List<Long> userIdList = userService.getUnderUserIdList(bladeUser).stream().map(User::getId).collect(Collectors.toList());
            queryWrapper.lambda().in(Goods::getCreateUser, userIdList);
        }
        queryWrapper.lambda().orderByDesc(Goods::getSell);
        return R.data(goodsService.list(queryWrapper));
    }

    /**
     * 指定日期商品排行
     */
    @GetMapping("/date-ranking-goods")
    @ApiOperationSupport(order = 4)
    @ApiOperation(value = "指定日期商品排行")
    public R<List<StatisticDateGoodsVo>> dateRankingGoods(@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") Date startTime, @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") Date endTime, BladeUser bladeUser) {
        if (Func.isEmpty(startTime)) {
            String today = DateUtil.formatDate(DateUtil.now());
            startTime = DateUtil.parse(today + " 00:00:00", DateUtil.PATTERN_DATETIME);
            endTime = DateUtil.parse(today + " 23:59:59", DateUtil.PATTERN_DATETIME);
        }

        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().between(Order::getCreateTime, startTime, endTime).eq(Order::getStatus, OrderStatusEnum.NORMAL.getStatus());

        if (!SecureUtil.isAdministrator()) {
            List<Long> userIdList = userService.getUnderUserIdList(bladeUser).stream().map(User::getId).collect(Collectors.toList());
            queryWrapper.lambda().in(Order::getFromUser, userIdList);
        }

        List<Order> orderList = orderService.list(queryWrapper);

        List<StatisticDateGoodsVo> statisticDateGoodsList = new ArrayList<>();
        for (Order order: orderList) {
            List<GoodsStyle> goodsStyleList = JsonUtil.parseArray(order.getAssociatedGoods(), GoodsStyle.class);
            for (GoodsStyle goodsStyle : goodsStyleList) {
                if (statisticDateGoodsList.size() == 0) {
                    statisticDateGoodsList.add(new StatisticDateGoodsVo() {{
                        setId(goodsStyle.getGoodsId());
                        setSell(1);
                    }});
                } else {
                    // 追加已存在商品的销售次数
                    for (StatisticDateGoodsVo statisticDateGoods : statisticDateGoodsList) {
                        if (statisticDateGoods.getId().equals(goodsStyle.getGoodsId())) {
                            statisticDateGoods.setSell(statisticDateGoods.getSell() + 1);
                            break;
                        }
                    }

                    // 如果列表不包含, 添加该商品到列表
                    List<Long> statisticDateGoodsIdList = statisticDateGoodsList.stream().map(StatisticDateGoodsVo::getId).collect(Collectors.toList());
                    if (!statisticDateGoodsIdList.contains(goodsStyle.getGoodsId())) {
                        statisticDateGoodsList.add(new StatisticDateGoodsVo() {{
                            setId(goodsStyle.getGoodsId());
                            setSell(1);
                        }});
                    }
                }
            }
        }

        // 获取商品名、图片
        if (Func.isNotEmpty(statisticDateGoodsList)) {
            List<Goods> goodsList = goodsService.listByIds(statisticDateGoodsList.stream().map(StatisticDateGoodsVo::getId).collect(Collectors.toList()));
            for (Goods goods : goodsList) {
                for (StatisticDateGoodsVo dateGoods : statisticDateGoodsList) {
                    if (dateGoods.getId().equals(goods.getId())) {
                        dateGoods.setName(goods.getName());
                        dateGoods.setPictureUrl(goods.getPictureUrl());
                    }
                }
            }
        }

        return R.data(statisticDateGoodsList);
    }

    /**
     * 图表概览
     */
    @GetMapping("/charts-summary")
    @ApiOperationSupport(order = 5)
    @ApiOperation(value = "图表概览")
    public R<List<StatisticSummaryVo>> chartsSummary(
            @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") Date starDate,
            @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") Date endDate,
            BladeUser bladeUser
    ) {
        starDate = DateUtil.parse(DateUtil.formatDate(starDate), DateUtil.PATTERN_DATE);
        endDate = DateUtil.parse(DateUtil.formatDate(endDate), DateUtil.PATTERN_DATE);
        List<Long> userIdList = new ArrayList<>();

        if (!SecureUtil.isAdministrator()) {
            userIdList = userService.getUnderUserIdList(bladeUser).stream().map(User::getId).collect(Collectors.toList());
        }

        QueryWrapper<Order> queryWrapperOrder = new QueryWrapper<>();
        queryWrapperOrder.lambda().between(Order::getCreateTime, starDate, endDate).eq(Order::getStatus, OrderStatusEnum.NORMAL.getStatus());
        if (!SecureUtil.isAdministrator()) {
            queryWrapperOrder.lambda().in(Order::getFromUser, userIdList);
        }

        // 指定时间段订单
        List<Order> orderList = orderService.list(queryWrapperOrder);

        // 时间段列表
        List<Date> dateList = new ArrayList<>();
        while (starDate.before(DateUtil.plusDays(endDate, 1))) {
            dateList.add(starDate);
            starDate = DateUtil.plusDays(starDate, 1);
        }


        List<StatisticSummaryVo> statisticSummaryList = new ArrayList<>();
        for (Date date: dateList) {
            String dateString = DateUtil.formatDate(date);
            StatisticSummaryVo statisticSummary = new StatisticSummaryVo() {{
                setRemark(dateString);
                setOrderSellAmount(new BigDecimal(0));
                setOrderSellCount(0);
            }};
            Date dateStart = DateUtil.parse(dateString + " 00:00:00", DateUtil.PATTERN_DATETIME);
            Date dateEnd = DateUtil.parse(dateString + " 23:59:59", DateUtil.PATTERN_DATETIME);
            for (Order order : orderList) {
                if (order.getCreateTime().after(dateStart) && order.getCreateTime().before(dateEnd)) {
                    statisticSummary.setOrderSellCount(statisticSummary.getOrderSellCount() + 1);
                    statisticSummary.setOrderSellAmount(statisticSummary.getOrderSellAmount().add(order.getTotalAmount()));
                }
            }
            statisticSummaryList.add(statisticSummary);
        }

        return R.data(statisticSummaryList);
    }
}
